package com.ruoyi.generator.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.generator.domain.*;
import com.ruoyi.generator.mapper.FromBuildConfigMapper;
import com.ruoyi.generator.mapper.FromBuildOptionsConfigMapper;
import com.ruoyi.generator.mapper.FromBuildRuleConfigMapper;
import com.ruoyi.generator.mapper.GenTableColumnMapper;
import com.ruoyi.generator.service.*;
import com.ruoyi.generator.util.GenUtils;
import com.ruoyi.generator.util.ModuleReqPrefixUtil;
import com.ruoyi.system.mapper.SysDictTypeMapper;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
import com.zgl.youshuda.core.utils.CommonUtil;
import com.zgl.youshuda.core.utils.CustomHashMap;
import com.zgl.youshuda.core.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 单设计_配置Service业务层处理
 *
 * @author XL
 * @date 2022-08-05 12:01:23
 */
@Service
@Slf4j
public class FromBuildConfigServiceImpl implements IFromBuildConfigService {
    @Autowired
    private FromBuildConfigMapper fromBuildConfigMapper;

    @Autowired
    private IFromBuildFormConfigService fromBuildFormConfigService;

    @Autowired
    private SysDictTypeMapper dictTypeMapper;

    @Autowired
    private ISysDictDataService dictDataService;

    @Autowired
    private IFromCrudBtnsService fromCrudBtnsService;

    @Autowired
    private IFromCrudTableConfigService fromCrudTableConfigService;

    /**
     * 数据表格自定义配置
     */
    @Autowired
    private IFromTableColumnConfigService fromTableColumnConfigService;

    @Autowired
    private GenTableColumnMapper genTableColumnMapper;

    @Autowired
    private IGenTableService iGenTableService;

    @Autowired
    private ISysDictTypeService dictTypeService;

    @Autowired
    private IFromBuildPageService fromBuildPageService;

    //配置标记，是否为所有配置都记录到config字段中
    private static String ConfigTag="CONFIG";

    /**
     * 查询单设计_配置
     *
     * @param id 单设计_配置ID
     * @return 单设计_配置
     */
    @Override
    public FromBuildConfig selectFromBuildConfigById(Long id) {
        return fromBuildConfigMapper.selectFromBuildConfigById(id);
    }

    /**
     * 查询单设计_配置列表
     *
     * @param fromBuildConfig 单设计_配置
     * @return 单设计_配置
     */
    @Override
    public List<FromBuildConfig> selectFromBuildConfigList(FromBuildConfig fromBuildConfig) {
        return fromBuildConfigMapper.selectFromBuildConfigList(fromBuildConfig);
    }

    /**
     * 新增单设计_配置
     *
     * @param fromBuildConfig 单设计_配置
     * @return 结果
     */
    @Override
    public int insertFromBuildConfig(FromBuildConfig fromBuildConfig) {
        return fromBuildConfigMapper.insertFromBuildConfig(fromBuildConfig);
    }

    /**
     * 修改单设计_配置
     *
     * @param fromBuildConfig 单设计_配置
     * @return 结果
     */
    @Override
    public int updateFromBuildConfig(FromBuildConfig fromBuildConfig) {
        return fromBuildConfigMapper.updateFromBuildConfig(fromBuildConfig);
    }

    /**
     * 批量删除单设计_配置
     *
     * @param ids 需要删除的单设计_配置ID
     * @return 结果
     */
    @Override
    public int deleteFromBuildConfigByIds(Long[] ids) {
        return fromBuildConfigMapper.deleteFromBuildConfigByIds(ids);
    }

    /**
     * 删除单设计_配置信息
     *
     * @param id 单设计_配置ID
     * @return 结果
     */
    @Override
    public int deleteFromBuildConfigById(Long id) {
        return fromBuildConfigMapper.deleteFromBuildConfigById(id);
    }

    /**
     * ==================================================================================================
     */
    /**
     * 获取表单设计字段配置信息
     */
    @Override
    public List getFormBuildConfig(String formBuildKey, String clientType) {

        List<FromBuildConfig> formBuildConfigs = fromBuildConfigMapper.getFormBuildConfig(formBuildKey, clientType);

        if(formBuildConfigs!=null && formBuildConfigs.size()>0){

            if(ConfigTag.equals(formBuildConfigs.get(0).getRemark())){
                //所有配置都记录到config字段中
                return formBuildConfigs.stream()
                        .map(item -> {
                            return JSONObject.parseObject(item.getConfig(), CustomHashMap.class);
                        })
                        .collect(Collectors.toList());
            }else{
                //配置信息记录在各字段中的方式
                /** 处理特殊的参数，如字符串转成对象 **/
                formBuildConfigs = dealSpecialParam(formBuildConfigs);

                return formBuildConfigs;
            }
        }
        return formBuildConfigs;
    }

//    /**
//     * 获取表单设计字段配置信息
//     */
//    @Override
//    public List<CustomHashMap> getFormBuildConfig(String formBuildKey, String clientType) {
//
//        List<FromBuildConfig> formBuildConfigs = fromBuildConfigMapper.getFormBuildConfig(formBuildKey, clientType);
//
//        List<CustomHashMap> configs = formBuildConfigs.stream()
//                .map(item -> {
//                    return JSONObject.parseObject(item.getConfig(), CustomHashMap.class);
//                })
//                .collect(Collectors.toList());
//
//        return configs;
//    }

    @Override
    public AjaxResult getFormBuildConfig(Map<String, Object> confParams) {

        /**
         * 1. 表单设计唯一key
         */
        String formBuildKey = String.valueOf(confParams.get("formBuildKey"));
        /**
         * 终端类型__PC_Mobile
         */
        String clientType = String.valueOf(confParams.get("clientType"));
        if (StringUtils.isEmpty(clientType)) {
            clientType = "PC";
        }
        /**
         * 判断参数是否为空
         */
        if (StringUtils.isEmpty(formBuildKey)) {
            return AjaxResult.error("操作失败，表单编码为空");
        }
        /**
         * 判断formBuildKey是否是以业务模块_菜单ID的形式
         */
        if (formBuildKey.indexOf("_") == -1 && !formBuildKey.equals("AttachmentFile")) {
            /**
             * 判断当前业务表是否对应有多个菜单，如果只有一个则返回对应菜单的表单设计信息，如果有多个则返回最基础的表单设计信息
             */
            /** 根据业务表模块名，获取对应所有的表单设计KEY **/
            List<Map<String, Object>> allFormBuildKeys = getAllFormBuildKeyByBusinessName(formBuildKey);
            if (allFormBuildKeys != null && allFormBuildKeys.size() == 1) {
                String _formBuildKey = String.valueOf(allFormBuildKeys.get(0).get("formBuildKey"));
                formBuildKey = StringUtils.isEmptyIncludeNull(_formBuildKey) ? formBuildKey : _formBuildKey;
            }
        }
        /**
         * 返回结果
         */
        Map<String,Object> result=new HashMap<>();
        //获取表单配置信息
        result.put("formBuildInfo",getFormBuildConfig(formBuildKey, clientType));

        if("PC".equals(clientType)){
            /** 获取表对应主键字段 **/
            result.put("formConfig", fromBuildFormConfigService.getFormConfig(formBuildKey));
        }else if ("Mobile".equals(clientType)){
            //移动端查询页面配置
            FromBuildPage fromBuildPage = new FromBuildPage();
            fromBuildPage.setBuildKey(formBuildKey);
            fromBuildPage.setStatus("0");
            List<FromBuildPage> fromBuildPages = fromBuildPageService.selectFromBuildPageList(fromBuildPage);
            if(fromBuildPages!=null && fromBuildPages.size()>0){
                result.put("pageConfig",fromBuildPages.get(0));
            }else{
                result.put("pageConfig",new FromBuildPage());
            }
        }
        return AjaxResult.success(result);
    }

    /**
     * 根据业务表模块名，获取对应所有的表单设计KEY
     * @param businessName
     * @return
     */
    @Override
    public List<Map<String,Object>> getAllFormBuildKeyByBusinessName(String businessName){
        return fromBuildConfigMapper.getAllFormBuildKeyByBusinessName(businessName);
    }

    /**
     * 处理特殊的参数，如字符串转成对象
     * @param configs
     * @return
     */
    private List<FromBuildConfig> dealSpecialParam(List<FromBuildConfig> configs){
        for(FromBuildConfig item:configs){

            if(item.getChildren()!=null && item.getChildren().size()>0){
                item.setChildren(dealSpecialParam(item.getChildren()));
            }
            //Style样式
            if(item.getStyle() !=null){
                try{
                    item.setStyle(JSONObject.parseObject(String.valueOf(item.getStyle())));
                }catch (Exception e){ }
            }
            /**
             * 多行文本框处理
             */
            if("textarea".equals(item.getModuleType().toLowerCase())){
                String defaultSize="{\"minRows\":4,\"maxRows\":4}";
                if(item.getAutosize() !=null){
                    String _autoSize = String.valueOf(item.getAutosize());
                    _autoSize = StringUtils.substring(_autoSize,_autoSize.indexOf("{"),_autoSize.lastIndexOf("}")+1);
                    defaultSize = _autoSize.replaceAll("\\\\+", "");
                }
                item.setAutosize(JSONObject.parseObject(defaultSize));
            }
        }
        return configs;
    }

    public List<Map<String, String>> getTableGenInfo(String formBuildKey) {

        return fromBuildConfigMapper.getTableGenInfo(formBuildKey);
    }

    /**
     * 特殊参数处理
     */
    public void paramDeal(List<FromBuildConfig> formBuildConfigInfoList) {

        for(FromBuildConfig item:formBuildConfigInfoList){
            //Style样式
            if(item.getStyle() !=null){
                try{
                    item.setStyle(JSONObject.parseObject(String.valueOf(item.getStyle())));
                }catch (Exception e){ }
            }
            //多行文本框
            if("textarea".equals(item.getModuleType().toLowerCase())) {
                try {
                    item.setAutosize(JSONObject.parseObject(String.valueOf(item.getAutosize())));
                } catch (Exception e) {
                    item.setAutosize(JSONObject.parseObject("{\"minRows\":4,\"maxRows\":4}"));
                }
            }
        }
    }

    /**
     * 特殊参数处理
     */
    private void paramDeal(JSONObject obj) throws Exception {
        obj.put("prefixIcon", obj.get("prefix-icon"));
        obj.remove("prefix-icon");
        obj.put("suffixIcon", obj.get("suffix-icon"));
        obj.remove("suffix-icon");
        obj.put("showWordLimit", obj.get("show-word-limit"));
        obj.remove("show-word-limit");
        obj.put("activeValue", obj.get("active-value"));
        obj.remove("active-value");
        obj.put("inactiveValue", obj.get("inactive-value"));
        obj.remove("inactive-value");
        /**
         * 样式
         */
        obj.remove("style");
        /**
         * 校验规则
         */
        obj.remove("regList");
        /**
         * 子组件
         */
        obj.remove("children");
    }

    /**
     * 处理流程节点信息
     */
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult saveFormInfo(GenTable genTable, String formBuildKey, String clientType, List<CustomHashMap> fromBuildConfigs) throws Exception {

        if (StringUtils.isEmptyIncludeNull(formBuildKey)) {
            return AjaxResult.error("表单设计编码不能为空");
        }
        /**
         * 删除表单配置
         */
        fromBuildConfigMapper.deleteFromBuildConfigByBuildKey(formBuildKey, clientType);

        if(fromBuildConfigs==null){
            return AjaxResult.success();
        }

        for (int i = 0; i < fromBuildConfigs.size(); i++) {
            CustomHashMap fromBuildConfig = fromBuildConfigs.get(i);
            /**
             * 显示顺序
             */
            fromBuildConfig.put("sort",i + 1);
            /**
             * 显示层级
             */
            fromBuildConfig.put("grade",1);
            /**
             * 终端类型__PC_Mobile
             */
            fromBuildConfig.put("clientType",clientType);
            /**
             * 处理表单信息
             */
            this.dealFormItem(genTable,formBuildKey, null, fromBuildConfig);
        }

        return AjaxResult.success();
    }

    /**
     * 处理表单组件
     */
    public void dealFormItem(GenTable genTable,String formBuildKey, CustomHashMap parent, CustomHashMap fromBuildConfig) throws Exception {
        /**
         * 处理新增字段
         */
        dealNewColumn(genTable,fromBuildConfig);
        /**
         * 设置流程编码
         */
        fromBuildConfig.put("buildKey",formBuildKey);
        /**
         * 设置表单组件UUID
         */
        fromBuildConfig.put("formUuid",GenUtils.getUUID());
        if(StringUtils.isEmptyIncludeNull(fromBuildConfig.getString("formId"))){
            fromBuildConfig.put("formId",fromBuildConfig.get("formUuid"));
        }
        /**
         * 将父组件的一些属性同步更新到子组件
         */
        if (parent != null) {
            /**
             * 设置表单父组件UUID
             */
            fromBuildConfig.put("parentFormUuid",parent.get("formUuid"));
        }
        /**
         * 判断是否存在子组件
         */
        fromBuildConfig.put("hasChildren","0");
        /**
         * 子组件
         */
        List<CustomHashMap> children = JSONArray.parseArray(JSONObject.toJSONString(fromBuildConfig.get("children")), CustomHashMap.class);
        if (children != null && children.size() >= 0) {
            fromBuildConfig.put("hasChildren","1");
            this.dealFormItemChild(genTable,formBuildKey, fromBuildConfig, children);
            fromBuildConfig.put("children",children);
        }
        String moduleType = fromBuildConfig.getString("moduleType");
        /**
         * 处理选项值
         */
        if(Arrays.asList("select","radio","checkbox","van-picker").contains(moduleType)){
            dealSelectionOptions(genTable,fromBuildConfig,formBuildKey);
        }

        /**
         * 判断当前组件是否是子表，如果是子表则需要获取出对应全类名
         */
        if (StringUtils.isNotEmpty(moduleType)  && (
                "ElTable".equals(moduleType)
                || "ElFileUpload".equals(moduleType))) {
            List<Map<String, String>> tableGenInfo = fromBuildConfigMapper.getTableGenInfo(fromBuildConfig.getString("vModel"));
            if (tableGenInfo.size() > 0) {
                //服务实现全类名
                fromBuildConfig.put("serviceName",StringUtils.format("{}.service.impl.{}ServiceImpl", tableGenInfo.get(0).get("packageName"), tableGenInfo.get(0).get("businessName")));
                /**
                 * 子表接口请求前缀，可能是平台标准方式，也可能是优树搭方式
                 */
                Map<String,String> prefixUrlInfo=new HashMap<>();
                //0zip压缩包 1自定义路径 2优树搭
                prefixUrlInfo.put("genType",tableGenInfo.get(0).get("genType"));
                //业务表生成ID
                String _tableId = fromBuildConfig.getString("bindMenu");
                if(StringUtils.isEmptyIncludeNull(_tableId)){
                    _tableId=String.valueOf(tableGenInfo.get(0).get("tableId"));
                }
                prefixUrlInfo.put("tableId",_tableId);
                //平台标准方式的访问前缀
                String baseUrl = StringUtils.format("/{}", tableGenInfo.get(0).get("businessName"));
                if(StringUtils.isNotEmptyIncludeNull(tableGenInfo.get(0).get("moduleName"))){
                    baseUrl = StringUtils.format("/{}/{}", ModuleReqPrefixUtil.getModuleRequestPrefix(tableGenInfo.get(0).get("moduleName")), tableGenInfo.get(0).get("businessName"));
                }
                prefixUrlInfo.put("baseUrlPrefix",baseUrl);
                fromBuildConfig.put("prefixUrl",JSONObject.toJSONString(prefixUrlInfo));
            }
        }
        /**
         * 特殊默认值处理
         */
        Object defaultValue = fromBuildConfig.get("defaultValue");
        if(defaultValue instanceof List){
            List defaultValues= (List) defaultValue;
            List collect = (List) defaultValues.stream()
                    .map(Object::toString)
                    .collect(Collectors.toList());

            fromBuildConfig.put("defaultValue",String.join(",", collect));
        }
        /**
         * 保存表单配置信息
         */
        fromBuildConfigMapper.insertFromBuildConfig(getSaveFromBuildConfig(formBuildKey,fromBuildConfig));
        /**
         * 修改对应字段配置信息
         */
        if(genTable!=null && genTable.getTableId()!=null){
            try{
                /** 当配置表单时，未对组件进行对应字段关联时，修改数据库字段会异常 **/
                genTableColumnMapper.updateGenTableColumnByJavaField(genNeedUpdateTableColumnInfo(genTable.getTableId(),fromBuildConfig));
            }catch (Exception e){}
        }
    }

    /**
     * 组装需要保存的表单配置信息
     * @param formBuildKey
     * @param fromBuildConfig
     * @return
     */
    private FromBuildConfig getSaveFromBuildConfig(String formBuildKey,CustomHashMap fromBuildConfig){
        FromBuildConfig _fromBuildConfig=new FromBuildConfig();
        //表单设计KEY
        _fromBuildConfig.setBuildKey(formBuildKey);
        //字段名
        _fromBuildConfig.setVModel(fromBuildConfig.getString("vModel"));
        //表单标题
        _fromBuildConfig.setLabel(fromBuildConfig.getString("label"));
        //组件类型
        _fromBuildConfig.setModuleType(fromBuildConfig.getString("moduleType"));
        //组件配置
        _fromBuildConfig.setConfig(JSONObject.toJSONString(fromBuildConfig));
        //显示顺序
        _fromBuildConfig.setSort(fromBuildConfig.getInteger("sort"));
        //显示层级
        _fromBuildConfig.setGrade(fromBuildConfig.getInteger("grade"));
        //终端类型__PC_Mobile
        _fromBuildConfig.setClientType(fromBuildConfig.getString("clientType"));
        //输入框中输入时就会触发
        _fromBuildConfig.setOnInput(fromBuildConfig.getString("onInput"));
        //输入框完成内容输入并失焦后触发
        _fromBuildConfig.setOnChange(fromBuildConfig.getString("onChange"));
        //获得焦点事件
        _fromBuildConfig.setOnFocus(fromBuildConfig.getString("onFocus"));
        //失去焦点事件
        _fromBuildConfig.setOnBlur(fromBuildConfig.getString("onBlur"));
        //点击事件
        _fromBuildConfig.setOnClick(fromBuildConfig.getString("onClick"));
        //是否启用信息脱敏
        String dataDesensitize = fromBuildConfig.getString("dataDesensitize");
        if(StringUtils.isNotEmptyIncludeNull(dataDesensitize) && "true".equals(dataDesensitize.toLowerCase())){
            //信息脱敏逻辑
            _fromBuildConfig.setDataDesensitizeLogic(fromBuildConfig.getString("dataDesensitizeLogic"));
        }
        //备注配置标记，是否为所有配置都记录到config字段中
        _fromBuildConfig.setRemark(ConfigTag);

        return _fromBuildConfig;
    }
    /**
     * 处理选择框选项值
     * @param genTable
     * @param fromBuildConfig
     * @throws Exception
     */
    public void dealSelectionOptions(GenTable genTable,CustomHashMap fromBuildConfig,String formBuildKey) throws Exception {
        if("1".equals(fromBuildConfig.getString("optionType"))){
            /**
             * 平台字典
             */
            List<FromBuildOptionsConfig> options = JSONArray.parseArray(JSONObject.toJSONString(fromBuildConfig.get("options")), FromBuildOptionsConfig.class);
            if (options != null && options.size() > 0) {
                //同步更新字典项，新增的字段不作处理
                if(!"1".equals(fromBuildConfig.getString("newColumn")) || "Mobile".equals(fromBuildConfig.getString("clientType"))) {
                    syncSysDict(genTable, fromBuildConfig, options);
                }
            }
        }else if("2".equals(fromBuildConfig.getString("optionType"))){
            //优树搭接口方式
            syncSysDict(genTable, fromBuildConfig, null);
        }
    }
    /**
     * 处理新增字段，创建到数据库表中
     */
    public void dealNewColumn(GenTable genTable,CustomHashMap fromBuildConfig) throws Exception {
        /**
         * 判断是否为新增字段
         */
        if(!"1".equals(fromBuildConfig.get("newColumn"))) {
            return;
        }
        try{
            if(StringUtils.isEmptyIncludeNull(fromBuildConfig.getString("newColumnName"))){
                throw new Exception(fromBuildConfig.get("label")+"字段名不能为空");
            }
            /**
             * 新增字段到数据库
             */
            GenTableColumn genTableColumn = new GenTableColumn();
            genTableColumn.setColumnName(fromBuildConfig.getString("newColumnName"));
            String newColumnTupe = fromBuildConfig.getString("newColumnType");
            if("varchar".equals(newColumnTupe)){
                Long maxlength = fromBuildConfig.getLong("maxlength");
                if(maxlength==null || maxlength<=0L){
                    fromBuildConfig.put("maxlength",fromBuildConfig.getLong("newColumnLength")/2);
                }else{
                    //以maxlength计算数据库表字段长度
                    long tabLength = maxlength * 2;
                    if(tabLength>4000){
                        newColumnTupe = "text";
                        fromBuildConfig.put("newColumnLength",0);
                    }else{
                        fromBuildConfig.put("newColumnLength",tabLength);
                    }
                }
            }
            if("timestamp".equals(newColumnTupe)){
                genTableColumn.setHtmlType(fromBuildConfig.getString("type"));
            }else{
                newColumnTupe=newColumnTupe+"("+fromBuildConfig.getString("newColumnLength")+")";
            }
            genTableColumn.setColumnType(newColumnTupe);
            String label = fromBuildConfig.getString("label");
            genTableColumn.setColumnComment(label);
            /**
             * 将字段备注拆出来
             */
            if(StringUtils.isNotEmptyIncludeNull(label)
                    && label.indexOf("__")>-1){
                String[] s = label.split("__");
                //中文字段名
                genTableColumn.setColumnComment(s[0]);
                fromBuildConfig.put("label",genTableColumn.getColumnComment());
                //字段描述
                genTableColumn.setColumnDesc(s[1]);
            }


            /**
             * 处理选项值
             * 以
             */
            List<FromBuildOptionsConfig> options = JSONArray.parseArray(JSONObject.toJSONString(fromBuildConfig.get("options")), FromBuildOptionsConfig.class);
            if (StringUtils.isEmptyIncludeNull(genTableColumn.getColumnDesc())
                    && options != null && options.size() > 0) {
                /**
                 * 规则：
                 * 	以S[..选项值..]  下拉框
                 * 	以R[..选项值..]  单选框
                 * 	以C[..选项值..]  复选框
                 * 选项值：以“_”分隔区分多个选项，每个选项以“:”分隔区分 值与描述
                 * 如：项目类型__r[1:软件开发_2:工程建设_3:咨询服务]
                 */
                String optionLabels = options.stream().map(item -> {
                    return item.getDictValue() + ":" + item.getDictLabel();
                }).collect(Collectors.joining("_"));
                String moduleType = fromBuildConfig.getString("moduleType");
                if(GenConstants.HTML_SELECT.equals(moduleType)){
                    optionLabels = "S["+optionLabels+"]";
                }
                if(GenConstants.HTML_RADIO.equals(moduleType)){
                    optionLabels = "R["+optionLabels+"]";
                }
                if(GenConstants.HTML_CHECKBOX.equals(moduleType)){
                    optionLabels = "C["+optionLabels+"]";
                }
                genTableColumn.setColumnDesc(optionLabels);
            }
            genTableColumn.setDictType(fromBuildConfig.getString("optionDictCode"));
            iGenTableService.addColumns(genTable,genTableColumn);

            if(StringUtils.isNotEmptyIncludeNull(genTableColumn.getDictType())){
                fromBuildConfig.put("optionDictCode",genTableColumn.getDictType());
            }

            fromBuildConfig.put("vModel",StringUtils.toCamelCase(genTableColumn.getColumnName()));
            fromBuildConfig.put("newColumn","0");

            String placeholder =fromBuildConfig.getString("placeholder");
            if(StringUtils.isNotEmptyIncludeNull(placeholder)
                    && placeholder.indexOf("__")>-1){
                String[] s = label.split("__");
                fromBuildConfig.put("placeholder",s[0]);
            }

        }catch (Exception e){
            throw new Exception("字段【"+fromBuildConfig.getString("label")+"】，原因："+e.getMessage());
        }

    }


    /**
     * 同步更新字典项
     * @param options
     */
    public void syncSysDict(GenTable genTable,CustomHashMap fromBuildConfig,List<FromBuildOptionsConfig> options ){
        // 字典类型编码
        String dictType = fromBuildConfig.getString("optionDictCode");
        if(StringUtils.isEmptyIncludeNull(dictType)){
            dictType="dict_"+fromBuildConfig.getString("buildKey")+"_"+fromBuildConfig.getString("vModel");
            fromBuildConfig.put("optionDictCode",dictType);
        }
        String optionType = fromBuildConfig.getString("optionType");
        /**
         * 字典信息
         */
        SysDictType dict = dictTypeMapper.checkDictTypeUnique(dictType);
        if (dict == null){
            //字典不存在时，新增
            dict=new SysDictType();
            //字典选项类型
            dict.setOptionType(optionType);
            //字典名称
            String dictName = fromBuildConfig.getString("label");
            if(StringUtils.isNotEmptyIncludeNull(genTable.getMenuLevels())){
                dictName = genTable.getMenuLevels()+"/"+fromBuildConfig.getString("label");
                dictName = dictName.replaceAll("\\\\+", "/").replaceAll("/+", "/");
                if(dictName.startsWith("/")){
                    dictName = dictName.substring(1);
                }
            }
            if("2".equals(optionType)){
                dictName+="【YSD】";
                dict.setYsdApi(fromBuildConfig.getString("ysdApi"));
                dict.setYsdApiCondition(fromBuildConfig.getString("ysdApiCondition"));
            }
            dict.setDictName(dictName);
            dict.setDictType(dictType);
            dict.setRemark(StringUtils.format("表【{}】中字段【{}】对应字典值",
                    fromBuildConfig.getString("buildKey")
                    ,fromBuildConfig.getString("vModel")));
            dict.setStatus("0");
            dictTypeService.insertDictType(dict);
        }else if("2".equals(optionType)){
            //字典选项类型
            dict.setOptionType(optionType);
            dict.setYsdApi(fromBuildConfig.getString("ysdApi"));
            dict.setYsdApiCondition(fromBuildConfig.getString("ysdApiCondition"));
            dictTypeService.updateDictType(dict);

            DictUtils.removeDictCache(dictType);
        }

        if("1".equals(optionType)){
            //删除之前字典项信息
            dictDataService.deleteDictDataByDictType(dictType);
            /**
             * 选项信息
             */
            for (int i = 0; i < options.size(); i++) {
                FromBuildOptionsConfig fromBuildOptionsConfig = options.get(i);
                SysDictData _dict = new SysDictData();
                //字典类型
                _dict.setDictType(dictType);
                //数据标签
                _dict.setDictLabel(fromBuildOptionsConfig.getDictLabel());
                //数据键值
                _dict.setDictValue(fromBuildOptionsConfig.getDictValue());
                //显示排序
                _dict.setDictSort((long) i);
                //状态
                _dict.setStatus("0");
                dictDataService.insertDictData(_dict);
            }
        }else{
            options = null;
        }

    }

//    /**
//     * 特殊参数处理
//     * @param fromBuildConfig
//     */
//    private void dealSpecialParams(FromBuildConfig fromBuildConfig){
//        //多行文本的最小行数与最大行数
//        if(fromBuildConfig.getAutosize()!=null && !(fromBuildConfig.getAutosize() instanceof String)){
//            fromBuildConfig.setAutosize(JSONObject.toJSONString(fromBuildConfig.getAutosize()));
//        }
//        //样式处理
//        if(fromBuildConfig.getStyle()!=null){
//            if(!"java.lang.String".equals(fromBuildConfig.getStyle().getClass().getTypeName())){
//                fromBuildConfig.setStyle(JSONObject.toJSONString(fromBuildConfig.getStyle()));
//            }
//        }
//    }

    /**
     * 处理组件对应子组件
     */
    public void dealFormItemChild(GenTable genTable,String formBuildKey, CustomHashMap parent, List<CustomHashMap> children) throws Exception {

        for (int i = 0; i < children.size(); i++) {
            CustomHashMap fromBuildConfig = children.get(i);
            /**
             * 显示顺序
             */
            fromBuildConfig.put("sort",i + 1);
            /**
             * 显示层级
             */
            fromBuildConfig.put("grade",2);
            /**
             * 终端类型__PC_Mobile
             */
            fromBuildConfig.put("clientType",parent.get("clientType"));

            this.dealFormItem(genTable,formBuildKey, parent, fromBuildConfig);

        }
    }

    /**
     * 获取需要修改的字段信息
     * @param fromBuildConfig
     * @return
     */
    private GenTableColumn genNeedUpdateTableColumnInfo(Long tableId,CustomHashMap fromBuildConfig){
        GenTableColumn genTableColumn=new GenTableColumn();
        /** 归属表编号 */
        genTableColumn.setTableId(tableId);
        /** JAVA字段名 */
        genTableColumn.setJavaField(fromBuildConfig.getString("vModel"));
        /** 字典类型 */
        genTableColumn.setDictType(fromBuildConfig.getString("optionDictCode"));
        /** 搜索表名__针对搜索文本框时的配置 **/
        genTableColumn.setSearchModel(fromBuildConfig.getString("searchModel"));
        /** 同步控件类型 **/
        if("datetime".equals(fromBuildConfig.getString("moduleType"))){
            genTableColumn.setHtmlType(fromBuildConfig.getString("type"));
        }else{
            genTableColumn.setHtmlType(fromBuildConfig.getString("moduleType"));
        }
//        /** 中文字段名 */
//        genTableColumn.setColumnComment(fromBuildConfig.getLabel());
//        /** 是否列表字段（1是） */
//        genTableColumn.setIsList(getGenTableColumnBoolStr(fromBuildConfig.getIsListShow()));
//        /** 列表宽度 */
//        if(StringUtils.isNotEmptyIncludeNull(fromBuildConfig.getListColumnWidth())){
//            genTableColumn.setColumnWidth(Integer.parseInt(fromBuildConfig.getListColumnWidth()));
//        }
//        /** 列表对齐方式 */
//        genTableColumn.setColumnAlign(fromBuildConfig.getListColumnAlign());
//        /** 是否查询字段（1是） */
//        genTableColumn.setIsQuery(getGenTableColumnBoolStr(fromBuildConfig.getIsQuery()));
//        /** 查询方式（EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围） */
//        genTableColumn.setQueryType(fromBuildConfig.getQueryType());

        return genTableColumn;
    }

    /**
     * 转换成gen_table_column表中的bool表达
     * @param bool
     * @return
     */
    private String getGenTableColumnBoolStr(String bool){
        if(StringUtils.isEmptyIncludeNull(bool)){
            return "0";
        }
        return "true".equals(bool.toLowerCase())?"1":"0";
    }

    /**
     * 根据业务表生成ID获取对应表配置信息
     * @param modelTag
     * @return
     */
    @Override
    public GenTableConfig getGenTableConfig(String modelTag){

        if(StringUtils.isEmptyIncludeNull(modelTag)){
            return null;
        }
        GenTableConfig genConfig = null;
        /**
         * modelTag 模块标识  有以下3种形式：
         * 1、 业务表ID_菜单ID  由 数字_数字 组成
         * 2、 业务表ID  由 数字 组成
         * 3、 业务表名
         */
        if(modelTag.matches("^[\\d]+_[\\d_]*$")){
            /** 业务表ID_菜单ID 的方式获取**/
            String[] menuTabIdInfo = modelTag.split("_");
            //由 业务表ID_菜单ID
            genConfig = iGenTableService.getGenConfigByMenuId(Long.valueOf(menuTabIdInfo[1]));
        }else{
            /** 业务表ID 或者 业务表名 的方式获取**/
            genConfig = iGenTableService.getGenConfigByTableIdOrName(modelTag);
        }
        return genConfig;
    }

    /**
     * 根据业务表生成ID获取对应表字段配置信息
     * @return
     */
    @Override
    public Map<String,Map> getGenTableColumnConfig(Long tableId,String linkColumn){
        Map<String, Map> genTableColumnConfig = genTableColumnMapper.getGenTableColumnConfig(tableId);
        if(StringUtils.isNotEmptyIncludeNull(linkColumn)){
            linkColumn = StringUtils.toUnderScoreCase(linkColumn);
            Map config = genTableColumnConfig.get(linkColumn);
            if(config!=null){
                config.put("queryType","EQ");
            }
            genTableColumnConfig.put(linkColumn,config);
        }
        return genTableColumnConfig;
    }

    /**
     * 根据模块标识获取对应表配置信息
     * modelTag 模块标识  有以下3种形式：
     * 1、 业务表ID_菜单ID  由 数字_数字 组成
     * 2、 业务表ID  由 数字 组成
     * 3、 业务表名
     */
    @Override
    public GenTableConfig getGenTableConfigIncludeColumn(String modelTag){
        return getGenTableConfigIncludeColumn(modelTag,true);

    }

    @Override
    public GenTableConfig getGenTableConfigIncludeColumn(String modelTag,boolean columnNameIsCamel){
        /**
         * 由  业务表ID_菜单ID 组成
         */
        if(StringUtils.isEmptyIncludeNull(modelTag)){
            return null;
        }
        GenTableConfig genConfig = getGenTableConfig(modelTag);
        if(genConfig==null){
            return null;
        }
        String perms = genConfig.getPerms();
        if(StringUtils.isNotEmptyIncludeNull(perms) && perms.indexOf(":")>-1){
            perms=perms.substring(0,perms.lastIndexOf(":"));
            genConfig.setPerms(perms);
        }

        /**
         * 获取业务表配置字段信息
         */
        List<GenTableColumn> fieldInfos = null;
        try {
            fieldInfos = getFieldInfoByTabName(genConfig.getTableName(),columnNameIsCamel,genConfig.getFormBuildKey());
        } catch (Exception e) {
            log.error("CRUD初始化，获取字段信息时异常：",e);
            return null;
        }
        genConfig.setFieldInfos(fieldInfos);
        /**
         * 表单设计是否配置
         */
        List<FromBuildConfig> formBuildConfigs = fromBuildConfigMapper.getFormBuildConfig(genConfig.getFormBuildKey(), "PC");
        genConfig.setFormBuildConfigOrNot(formBuildConfigs!=null && formBuildConfigs.size()>0?true:false);
        /**
         * 获取按钮配置信息
         */
        genConfig.setCrudBtnsList(fromCrudBtnsService.selectFromCrudBtnsByBuildKey(genConfig.getFormBuildKey()));
        /**
         * 当前模块表单配置信息
         */
        genConfig.setFormConfig(fromBuildFormConfigService.getFormConfig(genConfig.getFormBuildKey()));
        /**
         * 获取数据表配置信息
         */
        genConfig.setCrudTableConfig(fromCrudTableConfigService.selectFromCrudTableConfigByBuildKey(genConfig.getFormBuildKey()));

        return genConfig;

    }



    /**
     * 根据表名获取对应字段配置信息
     * @param tabName
     * @return
     */
    @Override
    public AjaxResult getColumnConfigByTableName(String tabName){
        return getColumnConfigByTableName(tabName,true);
    }

    public AjaxResult getColumnConfigByTableName(String tabName,boolean columnNameIsCamel){
        try {
            GenTableConfig genTableConfig = new GenTableConfig();
            genTableConfig.setFieldInfos(getFieldInfoByTabName(tabName,columnNameIsCamel,null));
            return AjaxResult.success(genTableConfig);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("获取业务表生成字段信息异常");
        }
    }

    /**
     * 根据表名获取对应字段信息
     * @param tabName
     * @param columnNameIsCamel  字段名是否需要驼峰格式
     * @return
     */
    private List<GenTableColumn> getFieldInfoByTabName(String tabName,boolean columnNameIsCamel,String formBuildKey){
        List<GenTableColumn> fieldInfo = iGenTableService.getFieldByTabName(tabName,columnNameIsCamel);
        // 获取表单设计中，各组件字段对应的onChange代码
        Map<String, Map<String, String>> eventCodeInfo = fromBuildConfigMapper.getOnChangeEventCode(formBuildKey);
        // 根据表单设置标识获取对应表格自定义配置信息
        Map<String, Map> customColumnConfig = fromTableColumnConfigService.getCustomColumnConfig(formBuildKey);
        // 遍历字段，处理特殊属性
        List<String> chooseType = Arrays.asList("select", "multipleSelect", "allowCreateSelect",
                "multipleallowCreateSelect", "radio", "checkbox");
        SysDictType _dictType;
        HashMap<String, Object> dictConfig;
        List<SysDictData> sysDictData;
        for (GenTableColumn columnConfig : fieldInfo) {
            //为存在字典的字典获取对应的选项信息
            if (StringUtils.isNotEmpty(columnConfig.getDictType()) && chooseType.contains(columnConfig.getHtmlType())) {
                sysDictData = dictTypeService.selectDictDataByType(columnConfig.getDictType());
                /**
                 * 字典懒加载判断
                 */
                _dictType = dictTypeService.selectDictTypeByType(columnConfig.getDictType());
                if(_dictType != null){
                    if("1".equals(_dictType.getBeLazy())){
                        dictConfig = new HashMap<>();
                        ArrayList<Object> dictItemsValue = new ArrayList<>();
                        sysDictData.forEach(item -> {
                            dictItemsValue.add(item.getDictValue());
                        });
                        // 已有的字典value
                        dictConfig.put("dictItems",dictItemsValue);
                        // 懒加载标识
                        dictConfig.put("beLazy",_dictType.getBeLazy());
                        // 字段类型标识
                        dictConfig.put("dictType",_dictType.getDictType());
                        columnConfig.setBeLazyDictConfig(dictConfig);
                    }
                    //懒加字典标识
                    columnConfig.setBeLazy(_dictType.getBeLazy());
                    //字典api
                    columnConfig.setYsdApi(_dictType.getYsdApi());
                    //字典数据
                    columnConfig.setDictItems(sysDictData);
                }else{
                    //字典数据
                    columnConfig.setDictItems(sysDictData);
                }
            }
            //字段长度
            columnConfig.setColumnLength(getColumnLength(columnConfig.getColumnType()));
            //记录事件代码信息
            if(eventCodeInfo!=null && eventCodeInfo.get(columnConfig.getColumnName()) != null){
                Map<String, String> codeInfo = eventCodeInfo.get(columnConfig.getColumnName());
                columnConfig.setOnChangeEventCode(codeInfo.get("onChangeEventCode"));
                //是否启用列表脱敏
                Map config = JsonUtil.parseJson(codeInfo.get("config"), Map.class);
                if(config!=null && "true".equals(String.valueOf(config.get("isListDesensitize")).toLowerCase())){
                    columnConfig.setDataDesensitizeLogic(String.valueOf(config.get("dataDesensitizeLogic")));
                }
            }
            //当存在表格自定义的情况
            if(customColumnConfig!=null && customColumnConfig.get(columnConfig.getColumnName())!=null){
                Map _config = customColumnConfig.get(columnConfig.getColumnName());
                columnConfig.setIsList(String.valueOf(_config.get("isList")));
                columnConfig.setIsAllowSort(String.valueOf(_config.get("isAllowSort")));
                columnConfig.setFixed(String.valueOf(_config.get("fixed")));
                columnConfig.setSort(Integer.parseInt(String.valueOf(_config.get("sort"))));
            }
        }
        return fieldInfo;
    }

    /**
     * 获取字段长度
     *
     * @param columnType 列类型
     * @return 截取后的列类型
     */
    private Integer getColumnLength(String columnType)
    {
        try{
            if (StringUtils.indexOf(columnType, "(") > 0)
            {
                String length = StringUtils.substringBetween(columnType, "(", ")");
                if(length.indexOf(",")>-1){
                    //有可能存在保留小位的情况
                    String[] _lengths = length.split(",");
                    return Integer.valueOf(_lengths[0]);
                }
                return Integer.valueOf(length);
            }
            else
            {
                return 0;
            }
        }catch (Exception e){
            return 0;
        }
    }
}
